package main

import "fmt"

func Count(ch chan int) {
	// 向对应的channel中写入一个数据
	// 在这个channel被读取前，这个操作是阻塞的
	fmt.Println("Counting")
	ch <- 1

}

// channel是Go语言在语言级别提供的goroutine间的通信方式。我们可以使用channel在两个或多个goroutine之间传递消息
// channel是进程内的通信方式，因此通过channel传递对象的过程和调用函数时的参数传递行为比较一致，比如也可以传递指针等。
// 跨进程通信，我们建议用分布式系统的方法来解决，比如使用Socket或者HTTP等通信协议。Go语言对于网络方面也有非常完善的支持。

// channel是类型相关的
// 一个channel只能传递一种类型的值，这个类型需要在声明channel时指定。
func main() {

	// 我们定义了一个包含10个channel的数组（名为 chs ）
	chs := make([]chan int, 10)
	for i := 0; i < 10; i++ {
		chs[i] = make(chan int)
		// 并把数组中的每个channel分配给10个不同的goroutine
		go Count(chs[i])
	}

	// 在所有的goroutine启动完成后，我们通过 <-ch 语句从10个channel中依次读取数据
	// 在对应的channel写入数据前，这个操作也是阻塞的
	// 这样，我们就用channel实现了类似锁的功能，进而保证了所有goroutine完成后主函数才返回
	for _, ch := range chs {
		//		fmt.Println(<-ch)
		<-ch
	}

	//	for k, v := range chs {
	//		fmt.Println(k)
	//		fmt.Println(v)
	//	}
	//	for index := range chs {
	//		fmt.Println(index)
	//	}
}
